---
title: Configuration
toc_max_heading_level: 6
---

import VersionLabel from '@site/src/components/Docs/VersionLabel';

We support configuration at both the project-level and user-level using a
[TOML](https://toml.io/en/) based `.prototools` file. This file can be used to pin versions of
tools, provide tool specific configuration, enable new tools via plugins, define proto settings, and
more.

## Locations<VersionLabel version="0.41.0" />

proto supports 3 locations in which a `.prototools` file can exist. These locations are used
throughout the command line and proto's own settings.

- `local` -> `./.prototools` (current directory)
- `global` -> `~/.proto/.prototools`
- `user` -> `~/.prototools`

> Local is a bit of a misnomer as a `.prototools` file can theoretically exist in any directory, but
> when reading/writing to a file, `local` refers to the current working directory.

### Where to configure?

With so many locations to store proto configuration, the question of where to store certain
configurations become blurred, especially when [resolution](#resolution-mode) comes into play. We
suggest the following locations:

- Default/fallback [versions](#pinning-versions) of tools -> `global`
- Project specific [versions](#pinning-versions) of tools -> `local`
- Project specific [settings](#settings) -> `local`
- Shared/developer [settings](#settings) -> `user`
- Non-project related -> `user`

## Resolution mode<VersionLabel version="0.40.0" />

When a `proto` command or shim is ran, we must find and load all applicable `.prototools` files. We
then deeply merge all of these configuration files into a final configuration object, with the
current directory taking highest precedence.

The order in which to resolve configuration can be defined using the `--config-mode` (`-c`) command
line option, or the `PROTO_CONFIG_MODE` environment variable. The following 4 modes are supported:

### `global`

In this mode, proto will _only_ load the `~/.proto/.prototools` file. This "global" file acts as
configuration at the user-level and allows for fallback settings.

```text
~/.proto/.prototools
```

### `local`

In this mode, proto will _only_ load the `.prototools` file in the current directory.

```text
./.prototools
```

### `upwards`

In this mode, proto will traverse upwards starting from the current directory, and load
`.prototools` within each directory, until we reach the system root or the user directory (`~`),
whichever comes first.

```text
~/Projects/app/.prototools (cwd)
~/Projects/.prototools
~/.prototools
```

> This is the default mode for the [`activate`](./commands/activate),
> [`install`](./commands/install), [`outdated`](./commands/outdated), and
> [`status`](./commands/status) commands.

### `upwards-global` / `all`

This mode works exactly like [`upwards`](#upwards) but with the functionality of [`global`](#global)
as well. The global `~/.proto/.prototools` file is appended as the final entry.

```text
~/Projects/app/.prototools (cwd)
~/Projects/.prototools
~/.prototools
~/.proto/.prototools
```

> This is the default mode for all other commands not listed above in `upwards`.

## Environment mode<VersionLabel version="0.29.0" />

We also support environment specific configuration, such as `.prototools.production` or
`.prototools.development`, when the `PROTO_ENV` environment variable is set. This is useful for
defining environment specific aliases, or tool specific configuration.

These environment aware settings take precedence over the default `.prototools` file, for the
directory it's located in, and are merged in the same way as the default configuration. For example,
the lookup order would be the following when `PROTO_ENV=production`:

```text
~/Projects/.prototools.production
~/Projects/.prototools
~/.prototools.production
~/.prototools
~/.proto/.prototools
```

> The global `~/.proto/.prototools` file does not support environment modes.

## Pinning versions

proto supports pinning versions of tools on a per-directory basis through our `.prototools`
configuration file. This file takes precedence during [version detection](./detection) and can be
created/updated with [`proto pin`](./commands/pin).

At its most basic level, you can map tools to specific versions, for the directory the file is
located in. A [version](./tool-spec) can either be a fully-qualified version, a partial version, a
range or requirement, or an alias.

```toml title=".prototools"
node = "16.16.0"
npm = "9"
go = "~1.20"
rust = "stable"
```

### Lock `proto` version<VersionLabel version="0.39.0" />

You can also pin the version of proto that you want all tools to execute with by adding a `proto`
version entry. This approach uses shims and dynamic version detection like other tools.

```toml title=".prototools"
proto = "0.38.0"
```

## Available settings

### `[env]`<VersionLabel version="0.29.0" />

This setting is a map of environment variables that will be applied to _all_ tools when they are
executed, or when [`proto activate`](./commands/activate) is ran in a shell profile. Variables
defined here _will not_ override existing environment variables (either passed on the command line,
or inherited from the shell).

```toml title=".prototools"
[env]
DEBUG = "*"
```

Additionally, `false` can be provided as a value, which will _remove_ the environment variable. This
is useful for removing inherited shell variables.

```toml title=".prototools"
[env]
DEBUG = false
```

Variables also support substitution using the syntax `${VAR_NAME}`. When using substitution,
variables in the current process and merged `[env]` can be referenced. Recursive substitution is not
supported!

> This functionality enables per-directory environment variables!

#### `file`<VersionLabel version="0.43.0" />

This is a special field that points to a dotenv file, relative from the current configuration file,
that will be loaded into the environment variables mapping. Variables defined in a dotenv file will
be loaded _before_ variables manually defined within `[env]`.

This feature utilizes the [dotenvy](https://github.com/allan2/dotenvy) crate for parsing dotfiles.

```toml title=".prototools"
[env]
file = ".env"
```

### `[settings]`

#### `auto-install`

When enabled, will automatically install a missing version of a tool when
[`proto run`](./commands/run) is ran, instead of erroring. Defaults to `false` or
`PROTO_AUTO_INSTALL`.

```toml title=".prototools"
[settings]
auto-install = true
```

:::warning

This functionality requires shims (not activation) and will only work after a tool has been
installed at least once. This is because the shim executable handles the interception and the shim
is created after a tool is installed.

:::

#### `auto-clean`

When enabled, will automatically clean up the proto store in the background, by removing unused
tools and outdated plugins. Defaults to `false` or `PROTO_AUTO_CLEAN`.

```toml title=".prototools"
[settings]
auto-clean = true
```

#### `builtin-plugins`<VersionLabel version="0.39.0" />

Can be used to customize the [built-in plugins](./tools#built-in) within proto. Can disable all
built-ins by passing `false`, or enabling a select few by name. Defaults to `true`, which enables
all.

```toml title=".prototools"
[settings]
# Disable all
builtin-plugins = false
# Enable some
builtin-plugins = ["node", "bun"]
```

#### `cache-duration`<VersionLabel version="0.50.1" />

The duration in seconds in which to cache downloaded plugins. Defaults to 30 days.

```toml title=".prototools"
[settings]
cache-duration = 3600
```

#### `detect-strategy`

The strategy to use when [detecting versions](./detection). Defaults to `first-available` or
`PROTO_DETECT_STRATEGY`.

- `first-available` - Will use the first available version that is found. Either from `.prototools`
  or a tool specific file (`.nvmrc`, etc).
- `prefer-prototools` - Prefer a `.prototools` version, even if found in a parent directory. If none
  found, falls back to tool specific file.
- `only-prototools` - Only use a version defined in `.prototools`. <VersionLabel version="0.34.0" />

```toml title=".prototools"
[settings]
detect-strategy = "prefer-prototools"
```

#### `pin-latest`

When defined and a tool is installed with the "latest" alias, will automatically pin the resolved
version to the configured location. Defaults to disabled or `PROTO_PIN_LATEST`.

- `global` - Pins globally to `~/.proto/.prototools`.
- `local` - Pins locally to `./.prototools` in current directory.
- `user` - Pins to the user's `~/.prototools` in their home directory.
  <VersionLabel version="0.41.0" />

```toml title=".prototools"
[settings]
pin-latest = "local"
```

#### `telemetry`

When enabled, we collect anonymous usage statistics for tool installs and uninstalls. This helps us
prioritize which tools to support, what tools or their versions may be broken, the plugins currently
in use, and more. Defaults to `true`.

```toml title=".prototools"
[settings]
telemetry = false
```

> The data we track is publicly available and
> [can be found here](https://github.com/moonrepo/proto/blob/master/crates/cli/src/telemetry.rs).

#### `unstable-lockfile`<VersionLabel version="0.51.0" />

When enabled, will create a `.protolock` file relative to this configuration file. The lockfile will
record and lock all tools, their versions, and checksums from the configuration file, ensuring
consistency across machines, and reliability.

```toml title=".prototools"
[settings]
unstable-lockfile = true
```

#### `unstable-registries`<VersionLabel version="0.51.0" />

A list of OCI registries to query for plugins by
[reference](https://oras.land/docs/concepts/reference). Registries will be queried in the order they
are configured. Each registry object supports the following fields:

- `registry` - The registry host, e.g. `ghcr.io`.
- `namespace` - The namespace (or organization) that the plugin belongs to.

```toml title=".prototools"
[settings]
unstable-registries = [
  { registry: "ghcr.io", namespace: "moonrepo" }
]
```

#### `url-rewrites`<VersionLabel version="0.50.0" />

Provides a mechanism for rewriting most URLs used by proto, such as those used for downloading
tools. This setting accepts a map of [Rust regular expressions](https://docs.rs/regex/latest/regex/)
to [replacement strings](https://docs.rs/regex/latest/regex/struct.Regex.html#method.replace). When
a URL is rewritten, all entries in the map are applied in order, and all matches are replaced.

```toml title=".prototools"
[settings.url-rewrites]
"github.com/(\\w+)/(\\w+)" = "gh-mirror.corp.com/$1/$2"
"mo+n" = "lunar"
```

The following types of URLs are rewritten:

- Tool download/checksum URLs (even from third-party plugins)
- Plugin download URLs
- Build script URLs
- Archive URLs

The following are _not_ rewritten:

- Git repository URLs
- proto version check/telemtry URLs

### `[settings.build]`<VersionLabel version="0.46.0" />

Can be used to customize the build from source flow.

#### `exclude-packages`

Configures a list of packages that should be excluded during installation.

```toml title=".prototools"
[settings.build]
exclude-packages = ["git", "python3", "libssl-dev"]
```

#### `install-system-packages`

When enabled, will install packages required for building using the system package manager. Defaults
to `true`.

```toml title=".prototools"
[settings.build]
install-system-packages = false
```

#### `system-package-manager`

Customize the system package manager to use when installing system packages and their dependencies.
By default we attempt to detect the package manager to use from the environment.

This setting accepts a map, where the key is the name of the
[operating system](https://doc.rust-lang.org/std/env/consts/constant.OS.html), and the value is the
[package manager](https://docs.rs/system_env/latest/system_env/enum.SystemPackageManager.html) to
use. Both the key and value are in kebab-case.

```toml title=".prototools"
[settings.build.system-package-manager]
windows = "choco"
```

#### `write-log-file`

When a build has completed, write a log file to the current directory. This is always `true` when a
build fails, but `false` otherwise.

```toml title=".prototools"
[settings.build]
write-log-file = true
```

### `[settings.http]`

Can be used to customize the HTTP client used by proto, primarily for requesting files to download,
available versions, and more.

#### `allow-invalid-certs`

When enabled, will allow invalid certificates instead of failing. This is an _escape hatch_ and
should only be used if other settings have failed. Be sure you know what you're doing! Defaults to
`false`.

```toml title=".prototools"
[settings.http]
allow-invalid-certs = true
```

#### `proxies`

A list of proxy URLs to use for requests. As an alternative, the `HTTP_PROXY` and `HTTPS_PROXY`
environment variables can be set. URLs that start with `http://` will be considered insecure, while
`https://` will be secure.

```toml title=".prototools"
[settings.http]
proxies = ["https://internal.proxy", "https://corp.net/proxy"]
```

#### `secure-proxies`<VersionLabel version="0.40.3" />

A list of proxy URLs that will be considered secure, regardless of the HTTP protocol.

```toml title=".prototools"
[settings.http]
secure-proxies = ["http://internal.proxy", "http://corp.net/proxy"]
```

#### `root-cert`

The path to a root certificate to use for requests. This is useful for overriding the native
certificate, or for using a self-signed certificate, especially when in a corporate/internal
environment. Supports `pem` and `der` files.

```toml title=".prototools"
[settings.http]
root-cert = "/path/to/root/cert.pem"
```

### `[settings.offline]`<VersionLabel version="0.41.0" />

Can be used to customize how we detect an internet connection for offline based logic. These
settings are useful if you're behind a VPN or corporate proxy.

#### `custom-hosts`

A list of custom hosts to ping. Will be appended to our
[default list of hosts](#override-default-hosts) and will be ran last.

```toml title=".prototools"
[settings.offline]
custom-hosts = ["proxy.corp.domain.com:80"]
```

#### `override-default-hosts`

If our default hosts are blocked or are too slow, you can disable pinging them by setting this
option to true. Our default hosts are Google DNS, Cloudflare DNS, and then Google and Mozilla hosts.

This should be used in parallel with [`custom-hosts`](#custom-hosts).

```toml title=".prototools"
[settings.offline]
override-default-hosts = true
```

#### `timeout`

The timeout in milliseconds to wait for a ping against a host to resolve. Default timeout is 750ms.

```toml title=".prototools"
[settings.offline]
timeout = 500
```

### `[plugins]`

This setting was renamed to [`[plugins.tools]`](#pluginstools) in v0.52 but exists for backwards
compatibility.

## Backend specific settings

### `[plugins.backends]`<VersionLabel version="0.52.0" />

Custom [backend plugins](./plugins) can be configured with the `[plugins.backends]` section.
[Learn more about this syntax](./plugins#enabling-plugins).

```toml title=".prototools"
[plugins.backends]
my-backend = "https://raw.githubusercontent.com/my/backend/master/proto-plugin.toml"
```

Once configured, you can manage a tool plugin using your custom backend:

```shell
$ proto install my-backend:tool-id
```

### `[backends.*]`<VersionLabel version="0.53.0" />

Backends support custom configuration that will be passed to their WASM plugin, which can be used to
control the behavior for _all_ tools managed by the backend. Please refer to the
[official documentation](./tool-spec#backends) around backends.

```toml title=".prototools"
[backends.example]
setting = true
```

### `[backends.*.env]`<VersionLabel version="0.53.0" />

This setting is a map of environment variables for a specific backend, and will be applied when that
backend is executed through a managed tool, or when [`proto activate`](./commands/activate) is ran
in a shell profile. These variables will override those defined in `[env]`. Refer to [`[env]`](#env)
for usage examples.

```toml title=".prototools"
[backends.example.env]
KEY = "value"
```

#### `file`<VersionLabel version="0.53.0" />

Like [`[env].file`](#file), this is a path to a dotenv file, relative from the current configuration
file, that will be loaded into the environment variables mapping for this specific backend.

```toml title=".prototools"
[backends.example.env]
file = "backend/.env"
```

## Tool specific settings

### `[plugins.tools]`<VersionLabel version="0.52.0" />

Custom [tool plugins](./plugins) can be configured with the `[plugins.tools]` section.
[Learn more about this syntax](./plugins#enabling-plugins).

```toml title=".prototools"
[plugins.tools]
my-tool = "https://raw.githubusercontent.com/my/tool/master/proto-plugin.toml"
```

Once configured, you can manage a tool plugin:

```shell
$ proto install my-tool
```

### `[tools.*]`

Tools support custom configuration that will be passed to their WASM plugin, which can be used to
control the business logic within the plugin. Please refer to the [official documentation](./tools)
of each tool (typically on their repository) for a list of available settings.

As an example, let's configure [Node.js](https://github.com/moonrepo/node-plugin) (using the `node`
identifier).

```toml title=".prototools"
npm = "bundled" # use bundled npm instead of specific version

[tools.node]
bundled-npm = true

[tools.npm]
shared-globals-dir = true
```

### `[tools.*.aliases]`

Aliases are custom and unique labels that map to a specific version, and can be configured manually
within `.prototools`, or by calling the [`proto alias`](./commands/alias) command.

```toml title=".prototools"
[tools.node.aliases]
work = "18"
oss = "20"
```

### `[tools.*.env]`<VersionLabel version="0.29.0" />

This setting is a map of environment variables for a specific tool, and will be applied when that
tool is executed, or when [`proto activate`](./commands/activate) is ran in a shell profile. These
variables will override those defined in `[env]`. Refer to [`[env]`](#env) for usage examples.

```toml title=".prototools"
[tools.node.env]
NODE_ENV = "production"
```

#### `file`<VersionLabel version="0.43.0" />

Like [`[env].file`](#file), this is a path to a dotenv file, relative from the current configuration
file, that will be loaded into the environment variables mapping for this specific tool.

```toml title=".prototools"
[tools.node.env]
file = "frontend/.env"
```

## GitHub Action

To streamline GitHub CI workflows, we provide the
[`moonrepo/setup-toolchain`](https://github.com/moonrepo/setup-toolchain) action, which can be used
to install `proto` globally, and cache the toolchain found at `~/.proto`.

```yaml title=".github/workflows/ci.yml"
# ...
jobs:
  ci:
    name: 'CI'
    runs-on: 'ubuntu-latest'
    steps:
      - uses: 'actions/checkout@v4'
      - uses: 'moonrepo/setup-toolchain@v0'
        with:
          auto-install: true
```
